package com.cskaoyan.duolai.clean.housekeeping.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cskaoyan.duolai.clean.common.expcetions.ForbiddenOperationException;
import com.cskaoyan.duolai.clean.common.model.dto.PageDTO;
import com.cskaoyan.duolai.clean.common.utils.ObjectUtils;
import com.cskaoyan.duolai.clean.housekeeping.converter.RegionServeConverter;
import com.cskaoyan.duolai.clean.housekeeping.dto.*;
import com.cskaoyan.duolai.clean.housekeeping.enums.HousekeepingStatusEnum;
import com.cskaoyan.duolai.clean.housekeeping.dao.entity.*;
import com.cskaoyan.duolai.clean.housekeeping.dao.mapper.*;
import com.cskaoyan.duolai.clean.housekeeping.request.RegionServeCommand;
import com.cskaoyan.duolai.clean.housekeeping.request.ServePageRequest;
import com.cskaoyan.duolai.clean.housekeeping.service.IHomeService;
import com.cskaoyan.duolai.clean.housekeeping.service.IRegionServeService;
import com.cskaoyan.duolai.clean.mysql.utils.PageUtils;
import com.cskaoyan.duolai.clean.redis.constants.RedisConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 服务表 服务实现类
 * </p>
 */
@Service
public class RegionServeServiceImpl extends ServiceImpl<RegionServeMapper, RegionServeDO> implements IRegionServeService {

    @Resource
    RegionServeConverter regionServeConverter;

    @Resource
    ServeItemMapper serveItemMapper;

    @Resource
    RegionServeMapper regionServeMapper;

    @Resource
    RegionMapper regionMapper;
    @Resource
    ServeTypeMapper serveTypeMapper;

    @Resource
    ServeSyncMapper serveSyncMapper;




    /**
     * 区域服务分页查询
     */
    @Override
    public PageDTO<RegionServeDTO> getPage(ServePageRequest servePageQueryReqDTO) {
        // 1. 创建分页对象
        Page<RegionServeDO> regionServeDOPage =
                new Page<>(servePageQueryReqDTO.getPageNo(), servePageQueryReqDTO.getPageSize());
        // 2. 调用Mapper层方法查询数据
        Page<RegionServeDO> regionServeDOIPage =
                baseMapper.queryRegionServeListByRegionId(servePageQueryReqDTO.getRegionId(), regionServeDOPage);
        // 3. 转换为DTO
        List<RegionServeDTO> regionServeDTOS =
                regionServeConverter.regionServeDOsToRegionServeDTOs(regionServeDOIPage.getRecords());
        // 4. 封装分页结果
        PageDTO<RegionServeDTO> regionServeDTOPageDTO = PageUtils.toPage(regionServeDOIPage, regionServeDTOS);

        return regionServeDTOPageDTO;
    }

    /*@Override
    public PageDTO<RegionServeDTO> getPage(ServePageRequest servePageQueryReqDTO) {
        // 创建分页对象
        Page<RegionServeDO> page = PageUtils.parsePageQuery(servePageQueryReqDTO, RegionServeDO.class);

        // 如果有区域ID，使用关联查询获取详细信息
        if (servePageQueryReqDTO.getRegionId() != null) {
            // 使用关联查询获取详细信息
            Page<RegionServeDO> regionServePage = regionServeMapper.queryRegionServeListByRegionId(
                    servePageQueryReqDTO.getRegionId(), page);

            // 转换为DTO
            List<RegionServeDTO> regionServeDTOList = regionServeConverter
                    .regionServeDOsToRegionServeDTOs(regionServePage.getRecords());

            // 返回分页结果
            return PageUtils.toPage(regionServePage, regionServeDTOList);
        } else {
            // 如果没有区域ID，使用原来的查询方式
            LambdaQueryWrapper<RegionServeDO> queryWrapper = Wrappers.<RegionServeDO>lambdaQuery();

            // 查询数据
            Page<RegionServeDO> regionServePage = baseMapper.selectPage(page, queryWrapper);

            // 获取服务详细信息 - 使用findDetailByIdDb方法
            List<RegionServeDTO> regionServeDTOList = new ArrayList<>();
            for (RegionServeDO regionServeDO : regionServePage.getRecords()) {
                RegionServeDTO regionServeDTO = regionServeConverter.regionServeDOToRegionServeDTO(regionServeDO);

                // 使用findDetailByIdDb方法获取详细信息
                RegionServeDetailDTO detailDTO = findDetailByIdDb(regionServeDO.getId());
                if (detailDTO != null) {
                    regionServeDTO.setServeItemName(detailDTO.getServeItemName());
                }

                // 查询服务类型信息
                ServeItemDO serveItemDO = serveItemMapper.selectById(regionServeDO.getServeItemId());
                if (serveItemDO != null) {
                    regionServeDTO.setReferencePrice(serveItemDO.getReferencePrice());
                    // 查询服务类型信息
                    ServeTypeDO serveTypeDO = serveTypeMapper.selectById(serveItemDO.getServeTypeId());
                    if (serveTypeDO != null) {
                        regionServeDTO.setServeTypeId(serveTypeDO.getId());
                        regionServeDTO.setServeTypeName(serveTypeDO.getName());
                    }
                }

                regionServeDTOList.add(regionServeDTO);
            }

            // 返回分页结果
            return PageUtils.toPage(regionServePage, regionServeDTOList);
        }
    }*/



    /**
     * 批量新增区域服务
     */
    @Override
    @Transactional
    public void batchAdd(List<RegionServeCommand> regionServeCommandList) {
        if (regionServeCommandList == null || regionServeCommandList.isEmpty()) {
            throw new ForbiddenOperationException("批量新增数据不能为空");
        }

        for (RegionServeCommand command : regionServeCommandList) {
            // 校验服务项是否存在
            ServeItemDO serveItemDO = serveItemMapper.selectById(command.getServeItemId());
            if (ObjectUtils.isNull(serveItemDO)) {
                throw new ForbiddenOperationException("服务项不存在");
            }

            // 校验区域是否存在
            RegionDO regionDO = regionMapper.selectById(command.getRegionId());
            if (ObjectUtils.isNull(regionDO)) {
                throw new ForbiddenOperationException("区域不存在");
            }

            // 校验是否已存在相同的区域服务
            LambdaQueryWrapper<RegionServeDO> queryWrapper = Wrappers.<RegionServeDO>lambdaQuery()
                    .eq(RegionServeDO::getServeItemId, command.getServeItemId())
                    .eq(RegionServeDO::getRegionId, command.getRegionId());
            Long count = baseMapper.selectCount(queryWrapper);
            if (count > 0) {
                throw new ForbiddenOperationException("该区域已存在此服务项");
            }

            // 创建区域服务对象
            RegionServeDO regionServeDO = new RegionServeDO();
            regionServeDO.setServeItemId(command.getServeItemId());
            regionServeDO.setRegionId(command.getRegionId());
            regionServeDO.setCityCode(regionDO.getCityCode());
            regionServeDO.setPrice(command.getPrice());
            regionServeDO.setSaleStatus(0); // 默认草稿状态
            regionServeDO.setIsHot(0); // 默认非热门

            // 保存到数据库
            baseMapper.insert(regionServeDO);
        }
    }

    /**
     * 服务价格修改
     */
    @Caching(
            put = {@CachePut(cacheNames = RedisConstants.CacheName.REGION_SERVE_DETAIL, key = "#id")},
            evict = {@CacheEvict(cacheNames = RedisConstants.CacheName.FIRST_PAGE_HOT_SERVE, key = "#regionId")}
    )
    @Override
    public RegionServeDetailDTO updatePrice(Long id, Long regionId, BigDecimal price) {
        // 查询区域服务是否存在
        RegionServeDO regionServeDO = baseMapper.selectById(id);
        if (ObjectUtils.isNull(regionServeDO)) {
            throw new ForbiddenOperationException("区域服务不存在");
        }



        // 更新价格
        LambdaUpdateWrapper<RegionServeDO> updateWrapper = Wrappers.<RegionServeDO>lambdaUpdate()
                .eq(RegionServeDO::getId, id)
                .set(RegionServeDO::getPrice, price);
        baseMapper.update(null, updateWrapper);


        // 更新价格
        RegionServeSyncDO regionServeSyncDO = new RegionServeSyncDO();
        regionServeSyncDO.setId(id);
        regionServeSyncDO.setPrice(price);
        serveSyncMapper.updateById(regionServeSyncDO);
        return findDetailByIdDb(id);

    }

    /**
     * 服务设置热门/取消
     */
    @CachePut(cacheNames = RedisConstants.CacheName.FIRST_PAGE_HOT_SERVE, key = "#regionId")
    @Override
    public List<RegionServeDetailDTO> changeHotStatus(Long id, Long regionId, Integer flag) {
        // 查询区域服务是否存在
        RegionServeDO regionServeDO = baseMapper.selectById(id);
        if (ObjectUtils.isNull(regionServeDO)) {
            throw new ForbiddenOperationException("区域服务不存在");
        }

        // 更新热门状态
        LambdaUpdateWrapper<RegionServeDO> updateWrapper = Wrappers.<RegionServeDO>lambdaUpdate()
                .eq(RegionServeDO::getId, id)
                .set(RegionServeDO::getIsHot, flag)
                .set(RegionServeDO::getHotTimeStamp, System.currentTimeMillis());
        baseMapper.update(null, updateWrapper);

//        return null;
        return findHotServeListByRegionId(regionId);
    }

    /**
     * 根据区域id和售卖状态查询关联服务数量
     */
    @Override
    public int queryServeCountByRegionIdAndSaleStatus(Long regionId, Integer saleStatus) {
        LambdaQueryWrapper<RegionServeDO> queryWrapper = Wrappers.<RegionServeDO>lambdaQuery()
                .eq(RegionServeDO::getRegionId, regionId);
        if (saleStatus != null) {
            queryWrapper.eq(RegionServeDO::getSaleStatus, saleStatus);
        }
        return Math.toIntExact(baseMapper.selectCount(queryWrapper));
    }

    /**
     * 根据服务项id和售卖状态查询关联服务数量
     */
    @Override
    public int queryServeCountByServeItemIdAndSaleStatus(Long serveItemId, Integer saleStatus) {
        LambdaQueryWrapper<RegionServeDO> queryWrapper = Wrappers.<RegionServeDO>lambdaQuery()
                .eq(RegionServeDO::getServeItemId, serveItemId);
        if (saleStatus != null) {
            queryWrapper.eq(RegionServeDO::getSaleStatus, saleStatus);
        }
        return Math.toIntExact(baseMapper.selectCount(queryWrapper));
    }

    /**
     * 删除区域服务
     */
    @Override
    @Transactional
    public void deleteById(Long id) {
        // 查询区域服务是否存在
        RegionServeDO regionServeDO = baseMapper.selectById(id);
        if (ObjectUtils.isNull(regionServeDO)) {
            throw new ForbiddenOperationException("区域服务不存在");
        }

        // 只有处于草稿状态的区域服务项才可以删除
        if (regionServeDO.getSaleStatus() != 0) {
            throw new ForbiddenOperationException("只有处于草稿状态的区域服务项才可以删除");
        }

        // 删除
        baseMapper.deleteById(id);
    }

    @Cacheable(cacheNames = RedisConstants.CacheName.REGION_SERVE_DETAIL, key = "#id")
    @Override
    public RegionServeDetailDTO findDetailByIdCache(Long id) {


        RegionServeDetailDTO detailByIdDb = findDetailByIdDb(id);
        if (detailByIdDb == null) {
            return new RegionServeDetailDTO();
        }

        return detailByIdDb;
    }

    /**
     * 根据id从数据库查询详情
     * @param id 服务id
     * @return
     */
    @Override
    public RegionServeDetailDTO findDetailByIdDb(Long id) {
        // 1. 查询区域服务项
        RegionServeDO regionServeDO = regionServeMapper.selectById(id);

        // 2. 判断区域的状态，如果使禁用状态，返回空集合
        RegionDO regionDO = regionMapper.selectById(regionServeDO.getRegionId());
        if (HousekeepingStatusEnum.DISABLE.getStatus() == regionDO.getActiveStatus()) {
            return new RegionServeDetailDTO();
        }

        // 3. 查询区域服务详情
        RegionServeDetailDO regionServeDetail = regionServeMapper.findRegionServeDetail(id);


        return regionServeConverter.regionServeDetailDO2DTO(regionServeDetail);
    }
    /*@Override
    public RegionServeDetailDTO findDetailByIdDb(Long id) {
        // 查询区域服务详细信息
        RegionServeDetailDO regionServeDetailDO = regionServeMapper.findRegionServeDetail(id);
        if (ObjectUtils.isNull(regionServeDetailDO)) {
            return null;
        }

        // 转换为DTO
        return regionServeConverter.regionServeDetailDO2DTO(regionServeDetailDO);
    }*/

    @Autowired
    IHomeService iHomeService;

    @Override
    public List<ServeTypeHomeDTO> refreshFirstPageRegionServeList(Long regionId) {
        return iHomeService.queryServeIconCategoryByRegionIdDb(regionId);
    }

    @Override
    public List<RegionServeDetailDTO> refreshFistPageHotServeList(Long regionId) {
        return findHotServeListByRegionId(regionId);
    }

    @Override
    public List<DisplayServeTypeDTO> refreshFirstPageServeTypeList(Long regionId) {
        return iHomeService.queryServeTypeListByRegionIdDb(regionId);
    }

    /**
     * 根据区域id查询精选推荐列表
     * @param regionId 区域id
     * @return
     */
    @Override
    public List<RegionServeDetailDTO> findHotServeListByRegionId(Long regionId) {
        // 1. 是否是已启用的区域
        RegionDO regionDO = regionMapper.selectById(regionId);
        if (HousekeepingStatusEnum.DISABLE.getStatus() == regionDO.getActiveStatus()) {
            return Collections.emptyList();
        }


        // 2. 查询精选推荐列表
        List<RegionServeDetailDO> hotServeListByRegionId = regionServeMapper.findHotServeListByRegionId(regionId);


        return regionServeConverter.regionServeDetailDOs2DTOs(hotServeListByRegionId);
    }

    @Override
    public List<DisplayServeTypeDTO> findServeTypeListByRegionId(Long regionId) {
        // 1. 是否是已启用的区域
        RegionDO regionDO = regionMapper.selectById(regionId);
        if (HousekeepingStatusEnum.DISABLE.getStatus() == regionDO.getActiveStatus()) {
            return Collections.emptyList();
        }


        // 2. 查询区域下的类型信息
        List<ServeTypeDO> serveTypeListByRegionId = regionServeMapper.findServeTypeListByRegionId(regionId);

        if (serveTypeListByRegionId == null) {
            return Collections.emptyList();
        }
        return regionServeConverter.serveTypeDOsToFirstPageServeTypeDTOs(serveTypeListByRegionId);
    }

    /**
     * 上架
     */
    @Caching(
            put = {@CachePut(cacheNames = RedisConstants.CacheName.REGION_SERVE_DETAIL, key = "#id")},
            evict = {
                    @CacheEvict(cacheNames = RedisConstants.CacheName.FIRST_PAGE_PARTIAL_SERVE_CACHE, key = "#result.regionId"),
                    @CacheEvict(cacheNames = RedisConstants.CacheName.FIRST_PAGE_HOT_SERVE, key = "#result.regionId"),
                    @CacheEvict(cacheNames = RedisConstants.CacheName.REGION_SERVE_TYPE, key = "#result.regionId")
            }
    )
    @Override
    @Transactional
    public RegionServeDetailDTO onSale(Long id) {
        // 查询区域服务是否存在
        RegionServeDO regionServeDO = baseMapper.selectById(id);
        if (ObjectUtils.isNull(regionServeDO)) {
            throw new ForbiddenOperationException("区域服务不存在");
        }

        // 查询服务项
        ServeItemDO serveItemDO = serveItemMapper.selectById(regionServeDO.getServeItemId());
        if (ObjectUtils.isNull(serveItemDO)) {
            throw new ForbiddenOperationException("服务项不存在");
        }

        // 查询服务类型
        ServeTypeDO serveTypeDO = serveTypeMapper.selectById(serveItemDO.getServeTypeId());
        if (ObjectUtils.isNull(serveTypeDO)) {
            throw new ForbiddenOperationException("服务类型不存在");
        }

        // 查询区域
        RegionDO regionDO = regionMapper.selectById(regionServeDO.getRegionId());
        if (ObjectUtils.isNull(regionDO)) {
            throw new ForbiddenOperationException("区域不存在");
        }

        // 当且仅当服务项，服务类型，以及区域状态都为启用状态的时候，且该区域服务项为下架/草稿状态，才可以在当前区域上架该服务项
        if (serveItemDO.getActiveStatus() != 2 || serveTypeDO.getActiveStatus() != 2
                || regionDO.getActiveStatus() != 2) {
            throw new ForbiddenOperationException("服务项、服务类型或区域状态不为启用状态，无法上架");
        }

        if (regionServeDO.getSaleStatus() != 0 && regionServeDO.getSaleStatus() != 1) {
            throw new ForbiddenOperationException("只有处于草稿或下架状态的区域服务项才可以上架");
        }

        // 更新为上架状态
        LambdaUpdateWrapper<RegionServeDO> updateWrapper = Wrappers.<RegionServeDO>lambdaUpdate()
                .eq(RegionServeDO::getId, id)
                .set(RegionServeDO::getSaleStatus, 2); // 2表示上架状态
        baseMapper.update(null, updateWrapper);



        /*// 查询并返回更新后的服务详情
        RegionServeDetailDO regionServeDetail = regionServeMapper.findRegionServeDetail(id);
        return regionServeConverter.regionServeDetailDO2DTO(regionServeDetail);*/
        addServeSync(id);
        return findDetailByIdDb(id);
    }

    private void addServeSync(Long serveId) {
        //服务信息
        RegionServeDO regionServe = baseMapper.selectById(serveId);
        //区域信息
        RegionDO region = regionMapper.selectById(regionServe.getRegionId());
        //服务项信息
        ServeItemDO serveItem = serveItemMapper.selectById(regionServe.getServeItemId());
        //服务类型
        ServeTypeDO serveType = serveTypeMapper.selectById(serveItem.getServeTypeId());

        RegionServeSyncDO regionServeSyncDO = regionServeConverter
                .regionServeToServeSyncDO(serveType, serveItem, regionServe, region.getCityCode());

        // 插入数据
        serveSyncMapper.insert(regionServeSyncDO);
    }


    /**
     * 下架
     */
    @Caching(
            evict = {
                    @CacheEvict(cacheNames = RedisConstants.CacheName.REGION_SERVE_DETAIL, key = "#id"),
                    @CacheEvict(cacheNames = RedisConstants.CacheName.FIRST_PAGE_HOT_SERVE, key = "#result.regionId"),
                    @CacheEvict(cacheNames = RedisConstants.CacheName.FIRST_PAGE_PARTIAL_SERVE_CACHE, key = "#result.regionId"),
                    @CacheEvict(cacheNames = RedisConstants.CacheName.REGION_SERVE_TYPE, key = "#result.regionId")
            }
    )
    @Override
    @Transactional
    public RegionServeDTO offSale(Long id) {
        // 查询区域服务是否存在
        RegionServeDO regionServeDO = baseMapper.selectById(id);
        if (ObjectUtils.isNull(regionServeDO)) {
            throw new ForbiddenOperationException("区域服务不存在");
        }

        // 只有处于上架状态的区域服务项才可以下架
        if (regionServeDO.getSaleStatus() != 2) {
            throw new ForbiddenOperationException("只有处于上架状态的区域服务项才可以下架");
        }

        // 更新为下架状态
        LambdaUpdateWrapper<RegionServeDO> updateWrapper = Wrappers.<RegionServeDO>lambdaUpdate()
                .eq(RegionServeDO::getId, id)
                .set(RegionServeDO::getSaleStatus, 1); // 1表示下架状态
        baseMapper.update(null, updateWrapper);



        RegionServeDO updatedRegionServe = baseMapper.selectById(id);
        serveSyncMapper.deleteById(id);
        return regionServeConverter.regionServeDOToRegionServeDTO(updatedRegionServe);
    }

    @Override
    public ServeDetailDTO findServeDetailById(Long id) {
        ServeDetailDO serveDetailById = regionServeMapper.findServeDetailById(id);
        return regionServeConverter.serveDetailDO2DTO(serveDetailById);
    }
}
